import { check, initExecute } from '../../utils/index.js';
import NameManger from '../../utils/NameManger.js';
import { NAME } from '../../consts/index.js';
import { Rule } from './Rule/index.js';
import Action from './Action/index.js';
// Form->Card->Space
class BuildArea {
	constructor(hook, ctx, param) {
		this.hook = hook;
		this.collect = [];
		this[NAME] = 'BuildArea';
		this.exec = initExecute.call(this.ctx = ctx);
		this.nameManger = new NameManger(this, param);
	}
	init() {
		const { hook, nameManger } = this;
		const {
			ruleConfig,
			spaceParam,
			hasRule = true,
			gutter = 8,
			span = 8,
			...o
		} = nameManger.config;
		this.other = o;
		const childsTarget = {};
		o.spaceParam = { span, gutter, ...spaceParam };
		this.param = Object.assign({
			hasRule,
			childsTarget,
			rule: new Rule(this, ruleConfig),
			childsProxy: hook.$m.$reactive(childsTarget),
		}, o);
		hook.hookNameManger(this);
		return this;
	}
	render({ is, ...info }, childs) {
		return this.hook.buildItem({ is })(info, childs);
	}
	add(...args) {
		this.collect.push(...args.flat(Infinity).map(v => {
			return check(v, 'BuildItem') ? v.useArea(this) : v;
		}));
		return this;
	}
	done(state = true) {
		const { ctx, other, param, collect } = this;
		const { $Space, Card, Form } = this.hook.$m;
		let {
			formParam,
			hasForm = true,
			cardParam,
			hasCard = true,
			spaceParam,
			hasSpace = true,
			children,
			// 作为card的属性
			...o
		} = other;

		let childs = collect;
		if (hasSpace) childs = { is: $Space, children: childs, ...spaceParam };
		// children与childs只能二取一，所以需要合并，将其余参数注入card，作为其参数配置
		if (hasCard) childs = { is: Card, children: [children, childs], ...o, ...cardParam };
		// form为区域的最外层， 即使嵌套在card插槽中的元素， 同样受到form控制
		const result = { node: childs };
		if (hasForm) {
			const param = this.hook.hookFormParam(this, formParam);
			// action用于表单的相关操作，如校验，重置等
			result.action = new Action(this);
			// node为最后用于渲染的JiessRender对象
			result.node = { is: Form, children: childs, ...param };
		}
		// 是否立即渲染
		if (state) {
			ctx.add(result.node);
			return result.action;
		} else {
			// 需要完整的数据
			return result;
		}
	}
}
export default BuildArea;